脚手架命令注册和执行过程开发
本周收获
- 如何设计高性能脚手架
- Node 多进程开发
- JavaScript 面向对象的实战技巧
主要内容
- 图解高性能脚手架架构设计方法
- 封装通用的 Package 和 Command 类
- 基于缓存 + Node 多进程实现动态命令加载和执行
- 将业务逻辑和脚手架框架彻底解耦
- Node 多进程开发——child_process源码分析
- 深入Node源码,看清
spawn
/exec
/execFile
/fork
的本质区别
- 深入Node源码,看清
脚手架命令注册
使用 commander
库
脚手架优化
为什么要优化
cli 安装速度慢:所有 package 都集成在 cli 里,因此当命令较多时,会减慢cli的安装速度
当前的cil结构
灵活性差:
init
命令只能使用@imooc-cli-dev/init
包,对于集团公司而言,每个项目组的init
命令可能都不相同,可能需要实现 init 命令动态化。- 团队A使用
@imooc-cli-dev/init
作为初始化模块 - 团队B使用自己开发的
@imooc-cli-dev/my-init
作为初始化模块
- 团队A使用
优化结果
脚手架命令动态加载功能架构设计
架构图
node
命令执行源码
node -e "require('./xx/yy/index.js')"
Package
对象功能
- 获取入口文件的路径
- 判断当前package是否存在
- 安装package
- 更新package
获取入口文件的路径 的实现
- 获取
package.json
所在目录,使用pkg-dir
库 - 读取
package.json
- 找到属性
main
,没有的话,找属性lib
,拼接为路径 - 路径兼容(macOS/windows)
安装package
使用 cnpm
的 npminstall
包安装。在执行 cnpm install
命令安装npm包时,实际用到的就是 npminstall
实例代码如下。npminstall()
返回一个 promise
对象。
const npminstall = require('npminstall');
const path = require('path');
const userhome = require('user-home')
npminstall({
root: path.resolve(userhome, '.imooc-cli-dev'), // 模块路径
storeDir: path.resolve(userhome, '.imooc-cli-dev', 'node_modules'), // 实际存储位置,root + node_modules
registry: 'https://registry.npm.taobao.org',
pkgs: [
{ name: 'foo', version: '~1.0.0' },
], // 指定安装的包名和版本
});
更新package
fs-extra
fs
的替代品。添加了fs
没有的文件系统方法,并支持Promise
。mkdir -p
递归创建文件夹
获取最新
npm
模块版本号查询最新版本号对应的路径是否存在
如果不存在,直接安装最新版本